﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
using YasharEl.Infrastructure.Core.Locations;
using YasharEl.Infrastructure.Core.ServiceModel;
using YasharEl.Infrastructure.ProcessEngine.ServiceModel;
using YasharEl.Infrastructure.ServiceModel;

namespace YasharEl.Infrastructure.AllModules.AcceptanceTests.ProcessEngine.Steps
{
    [Binding]
    public class StartBasicInfrastructureTestProcessStepDefinition
    {
        #region Fields

        private RetrieveProcessDefinitionRequest _retrieveProcessDefinitionRequest;
        private RetrieveProcessDefinitionResponse _retrieveProcessDefinitionResponse;
        private StartProcessRequest _startProcessRequest;
        private StartProcessResponse _startProcessResponse;
        private PropertyDefinitionDTO _testLongProperty;
        private PropertyDefinitionDTO _testStringProperty;
        private PropertyDefinitionDTO _testIntegerProperty;
        private PropertyDefinitionDTO _testAddressProperty;
        private PropertyDefinitionDTO _testBooleanProperty;
        private PropertyDefinitionDTO _testDecimalProperty;
        private PropertyDefinitionDTO _testDoubleProperty;
        private PropertyDefinitionDTO _testDateTimeProperty;
        private PropertyDefinitionDTO _testDelayTimeInMillisecondsProperty;

        private RetrieveProcessResponse _retrieveProcessResponse;
        private ProcessDTO _createdProcess;

        #endregion

        #region Given

        [Given(@"I have filled out the process definition id : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void GivenIHaveFilledOutTheProcessDefinitionId(long processDefinitionId)
        {
            _retrieveProcessDefinitionRequest = new RetrieveProcessDefinitionRequest()
            {
                ProcessDefinitionId = processDefinitionId
            };

            _startProcessRequest = new StartProcessRequest()
            {
                ProcessDefinitionId = processDefinitionId,
                Inputs = new PropertyAssignments(),
            };
        }

        [Given(@"I have filled out the application id : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void GivenIHaveFilledOutTheApplicationId(long applicationId)
        {
            _retrieveProcessDefinitionRequest.ApplicationId = applicationId;
            _startProcessRequest.ApplicationId = applicationId;
        }

        [Given(@"I have filled out the process owner : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void GivenIHaveFilledOutTheProcessOwner(long owner)
        {
            _startProcessRequest.Owner = owner;
        }


        #endregion

        #region When

        [When(@"I retrieve process metadata from process definitions catalog")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void WhenIRetrieveProcessMetadataFromProcessDefinitionsCatalog()
        {
            using (ServiceProxy<IProcessMetadataRetriever> processMetadataRetrieverProxy = new ServiceProxy<IProcessMetadataRetriever>())
            {
                _retrieveProcessDefinitionResponse = processMetadataRetrieverProxy.Proxy.RetrieveProcessDefinition(_retrieveProcessDefinitionRequest);
            }
        }

        [When(@"I start new infrastructure test process")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void WhenIStartNewInfrastructureTestProcess()
        {
            using (ServiceProxy<IProcessExecutor> processExecutorProxy = new ServiceProxy<IProcessExecutor>())
            {
                _startProcessResponse  = processExecutorProxy.Proxy.StartProcess(_startProcessRequest);
            }
        }

        #endregion

        #region Then

        [Then(@"I should receive valid process metadata response")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenIShouldReceiveValidProcessMetadataResponse()
        {
            Assert.IsNotNull(_retrieveProcessDefinitionResponse);
            Assert.IsNotNull(_retrieveProcessDefinitionResponse.ProcessDefinition);
        }

        [Then(@"the returned process metadata information has defined properties")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasDefinedProperties()
        {
            Assert.IsNotNull(_retrieveProcessDefinitionResponse.DefinedProperties);
            Assert.IsTrue(_retrieveProcessDefinitionResponse.DefinedProperties.Count > 0);
        }

        [Then(@"the returned process metadata information has 'TestLongProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestLongPropertyProperty()
        {
            _testLongProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestLongProperty");
            Assert.IsNotNull(_testLongProperty);
        }

        [Then(@"the 'TestLongProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestLongPropertyPropertyContainsTheTestLongPropertyPropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testLongProperty.PropertyName);
        }

        [Then(@"the 'TestLongProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestLongPropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testLongProperty.);
        }

        [Then(@"the returned process metadata information has 'TestStringProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestStringPropertyProperty()
        {
            _testStringProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestStringProperty");
            Assert.IsNotNull(_testStringProperty);
        }

        [Then(@"the 'TestStringProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestLongPropertyPropertyContainsTheTestStringPropertyPropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testStringProperty.PropertyName);
        }

        [Then(@"the 'TestStringProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestStringPropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testStringProperty.);
        }

        [Then(@"the returned process metadata information has 'TestIntegerProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestIntegerPropertyProperty()
        {
            _testIntegerProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestIntegerProperty");
            Assert.IsNotNull(_testStringProperty);
        }

        [Then(@"the 'TestIntegerProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestLongPropertyPropertyContainsTheTestIntegerPropertyPropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testIntegerProperty.PropertyName);
        }

        [Then(@"the 'TestIntegerProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestIntegerPropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testIntegerProperty.);
        }

        [Then(@"the returned process metadata information has 'TestDoubleProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestDoublePropertyProperty()
        {
            _testDoubleProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestDoubleProperty");
            Assert.IsNotNull(_testDoubleProperty);
        }

        [Then(@"the 'TestDoubleProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestDoublePropertyPropertyContainsThePropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testDoubleProperty.PropertyName);
        }

        [Then(@"the 'TestDoubleProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestDoublePropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testDoubleProperty.);
        }

        [Then(@"the returned process metadata information has 'TestDecimalProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestDecimalPropertyProperty()
        {
            _testDecimalProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestDecimalProperty");
            Assert.IsNotNull(_testDecimalProperty);
        }

        [Then(@"the 'TestDecimalProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestDecimalPropertyPropertyContainsThePropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testDecimalProperty.PropertyName);
        }

        [Then(@"the 'TestDecimalProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestDecimalPropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testDecimalProperty.);
        }

        [Then(@"the returned process metadata information has 'TestDateTimeProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestDateTimePropertyProperty()
        {
            _testDateTimeProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestDateTimeProperty");
            Assert.IsNotNull(_testDateTimeProperty);
        }

        [Then(@"the 'TestDateTimeProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestDateTimePropertyPropertyContainsThePropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testDateTimeProperty.PropertyName);
        }

        [Then(@"the 'TestDateTimeProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestDateTimePropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testDateTimeProperty.);
        }

        [Then(@"the returned process metadata information has 'TestBooleanProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestBooleanPropertyProperty()
        {
            _testBooleanProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestBooleanProperty");
            Assert.IsNotNull(_testBooleanProperty);
        }

        [Then(@"the 'TestBooleanProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestBooleanPropertyPropertyContainsThePropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testBooleanProperty.PropertyName);
        }

        [Then(@"the 'TestBooleanProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestBooleanPropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testBooleanProperty.);
        }

        [Then(@"the returned process metadata information has 'TestAddressProperty' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasTestAddressPropertyProperty()
        {
            _testAddressProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "TestAddressProperty");
            Assert.IsNotNull(_testAddressProperty);
        }

        [Then(@"the 'TestAddressProperty' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestAddressPropertyPropertyContainsThePropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testAddressProperty.PropertyName);
        }

        [Then(@"the 'TestAddressProperty' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestAddressPropertyPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testAddressProperty.);
        }

        [Then(@"the returned process metadata information has 'DelayTimeInMilliseconds' property")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheReturnedProcessMetadataInformationHasDelayTimeInMillisecondsProperty()
        {
            _testDelayTimeInMillisecondsProperty = _retrieveProcessDefinitionResponse.DefinedProperties.Find((d) => d.PropertyKey == "DelayTimeInMilliseconds");
            Assert.IsNotNull(_testDelayTimeInMillisecondsProperty);
        }

        [Then(@"the 'DelayTimeInMilliseconds' property contains the property name : '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheTestLongPropertyPropertyContainsTheDelayTimeInMillisecondsPropertyName(string name)
        {
            Assert.AreEqual<string>(name, _testDelayTimeInMillisecondsProperty.PropertyName);
        }

        [Then(@"the 'DelayTimeInMilliseconds' property is required")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheDelayTimeInMillisecondsPropertyIsRequired()
        {
            // TODO: Implement is required
            //Assert.AreEqual<string>(name, _testDelayTimeInMillisecondsProperty.);
        }

        [Then(@"I set required 'TestLongProperty' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestLongPropertyPropertyTo(long testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testLongProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testLongProperty,
                    ValueContainer = new PropertyValueLongDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I set required 'TestStringProperty' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestStringPropertyPropertyTo(string testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testStringProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testStringProperty,
                    ValueContainer = new PropertyValueStringDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I set required 'TestIntegerProperty' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestIntegerPropertyPropertyTo(int testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testIntegerProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testIntegerProperty,
                    ValueContainer = new PropertyValueIntegerDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I set required 'TestDoubleProperty' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestDoublePropertyPropertyTo(double testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testDoubleProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testDoubleProperty,
                    ValueContainer = new PropertyValueDoubleDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I set required 'TestDecimalProperty' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestDecimalPropertyPropertyTo(decimal testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testDecimalProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testDecimalProperty,
                    ValueContainer = new PropertyValueDecimalDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I set required 'TestDateTimeProperty' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestDateTimePropertyPropertyTo(DateTime testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testDateTimeProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testDateTimeProperty,
                    ValueContainer = new PropertyValueDateTimeDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I set required 'TestBooleanProperty' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestBooleanPropertyPropertyTo(bool testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testBooleanProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testBooleanProperty,
                    ValueContainer = new PropertyValueBooleanDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I set required 'TestAddressProperty' property to : '(.*)', '(.*)', (.*), (.*), (.*), (.*), '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredTestAddressPropertyPropertyTo(string city, string street, int zipCode, int houseNumber,int apartmentNumber, int poBox, string entrance)
        {
            _startProcessRequest.Inputs.Add(
                _testAddressProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testAddressProperty,
                    ValueContainer = new PropertyValueAddressDTO()
                    {
                        Value = new Address(city, street, zipCode, houseNumber, apartmentNumber, poBox, entrance)
                    }
                });
        }

        [Then(@"I set required 'DelayTimeInMilliseconds' property to : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenISetRequiredDelayTimeInMillisecondsPropertyTo(long testValue)
        {
            _startProcessRequest.Inputs.Add(
                _testDelayTimeInMillisecondsProperty.PropertyKey,
                new PropertyAssignmentDTO()
                {
                    PropertyDefinition = _testDelayTimeInMillisecondsProperty,
                    ValueContainer = new PropertyValueLongDTO()
                    {
                        Value = testValue
                    }
                });
        }

        [Then(@"I should receive valid start infrastructure test process request")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenIShouldReceiveValidStartInfrastructureTestProcessRequest()
        {
            Assert.IsNotNull(_startProcessResponse);
            Assert.IsNotNull(_startProcessResponse.StartedProcess);
        }

        [Then(@"the response message includes the new started process workflow identifier")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheResponseMessageIncludesTheNewStartedProcessWorkflowIdentifier()
        {
            Assert.IsTrue(_startProcessResponse.StartedProcess.WorkflowInstanceId != Guid.Empty);
        }

        [Then(@"the processes lists includes the previously created process with active status")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheProcessesListsIncludesThePreviouslyCreatedProcessWithActiveStatus()
        {
            try
            {
                using (ServiceProxy<IProcessRetriever> processRetrieverProxy = new ServiceProxy<IProcessRetriever>())
                {
                    _retrieveProcessResponse = processRetrieverProxy.Proxy.RetrieveProcess(
                        new RetrieveProcessRequest()
                        {
                            ApplicationId = _startProcessRequest.ApplicationId,
                            WorkflowInstanceId = _startProcessResponse.StartedProcess.WorkflowInstanceId
                        }
                    );
                }
            }
            finally
            {
                Assert.IsNotNull(_retrieveProcessResponse);
                Assert.IsNotNull(_retrieveProcessResponse.FoundProcess);
                Assert.IsTrue(_retrieveProcessResponse.FoundProcess.CurrentStatus.ProcessStatus == ProcessStatus.Active);

                _createdProcess = _retrieveProcessResponse.FoundProcess;
            }
        }

        [Then(@"the created process owned by : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessOwnedBy(long owner)
        {
            Assert.IsNotNull(_createdProcess.Owner);
            Assert.AreEqual<long>(owner, _createdProcess.Owner.ParticipantId);
        }

        [Then(@"the created process has prototyped properties assignments")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessHasPrototypedPropertiesAssignments()
        {
            Assert.IsNotNull(_createdProcess.PropertyAssignments);
            Assert.IsTrue(_createdProcess.PropertyAssignments.Count > 0);
        }

        [Then(@"the created process contains the previously set 'TestLongProperty' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestLongPropertyPropertyWithValue(long testValue)
        {
            KeyValuePair<string,PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestLongProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueLongDTO));
            Assert.AreEqual<long>(testValue, ((PropertyValueLongDTO)pair.Value.ValueContainer).Value);
        }

        [Then(@"the created process contains the previously set 'TestStringProperty' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestStringPropertyPropertyWithValue(string testValue)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestStringProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueStringDTO));
            Assert.AreEqual<string>(testValue, ((PropertyValueStringDTO)pair.Value.ValueContainer).Value);
        }

        [Then(@"the created process contains the previously set 'TestIntegerProperty' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestIntegerPropertyPropertyWithValue(int testValue)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestIntegerProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueIntegerDTO));
            Assert.AreEqual<int>(testValue, ((PropertyValueIntegerDTO)pair.Value.ValueContainer).Value);
        }

        [Then(@"the created process contains the previously set 'TestDoubleProperty' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestDoublePropertyPropertyWithValue(double testValue)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestDoubleProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueDoubleDTO));
            Assert.AreEqual<double>(testValue, ((PropertyValueDoubleDTO)pair.Value.ValueContainer).Value);
        }

        [Then(@"the created process contains the previously set 'TestDecimalProperty' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestDecimalPropertyPropertyWithValue(decimal testValue)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestDecimalProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueDecimalDTO));
            Assert.AreEqual<decimal>(testValue, ((PropertyValueDecimalDTO)pair.Value.ValueContainer).Value);
        }

        [Then(@"the created process contains the previously set 'TestDateTimeProperty' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestDateTimePropertyPropertyWithValue(DateTime testValue)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestDateTimeProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueDateTimeDTO));
            Assert.AreEqual<DateTime>(testValue, ((PropertyValueDateTimeDTO)pair.Value.ValueContainer).Value);
        }

        [Then(@"the created process contains the previously set 'TestBooleanProperty' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestBooleanPropertyPropertyWithValue(bool testValue)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestBooleanProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueBooleanDTO));
            Assert.AreEqual<bool>(testValue, ((PropertyValueBooleanDTO)pair.Value.ValueContainer).Value);
        }

        [Then(@"the created process contains the previously set 'TestAddressProperty' property with value : '(.*)', '(.*)', (.*), (.*), (.*), (.*), '(.*)'")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetTestAddressPropertyPropertyWithValue(
            string city, string street, int zipCode, int houseNumber, int apartmentNumber, int poBox, string entrance)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "TestAddressProperty");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueAddressDTO));
            Assert.IsNotNull(pair.Value.ValueContainer.Value);
            Assert.AreEqual<string>(city, ((PropertyValueAddressDTO)pair.Value.ValueContainer).Value.City);
            Assert.AreEqual<string>(street, ((PropertyValueAddressDTO)pair.Value.ValueContainer).Value.Street);
            Assert.AreEqual<int>(zipCode, ((PropertyValueAddressDTO)pair.Value.ValueContainer).Value.ZipCode);
            Assert.AreEqual<int?>(houseNumber, ((PropertyValueAddressDTO)pair.Value.ValueContainer).Value.HouseNumber);
            Assert.AreEqual<int?>(apartmentNumber, ((PropertyValueAddressDTO)pair.Value.ValueContainer).Value.ApartmentNumber);
            Assert.AreEqual<int?>(poBox, ((PropertyValueAddressDTO)pair.Value.ValueContainer).Value.POBox);
            Assert.AreEqual<string>(entrance, ((PropertyValueAddressDTO)pair.Value.ValueContainer).Value.Entrance);
        }

        [Then(@"the created process contains the previously set 'DelayTimeInMilliseconds' property with value : (.*)")]
        [Scope(Tag = "StartBasicInfrastructureTestProcess")]
        public void ThenTheCreatedProcessContainsThePreviouslySetDelayTimeInMillisecondsPropertyWithValue(long testValue)
        {
            KeyValuePair<string, PropertyAssignmentDTO> pair = _createdProcess.PropertyAssignments.FirstOrDefault((k) => k.Key == "DelayTimeInMilliseconds");
            Assert.IsNotNull(pair);
            Assert.IsNotNull(pair.Value);
            Assert.IsNotNull(pair.Value.PropertyDefinition);
            Assert.IsNotNull(pair.Value.ValueContainer);
            Assert.IsInstanceOfType(pair.Value.ValueContainer, typeof(PropertyValueLongDTO));
            Assert.AreEqual<long>(testValue, ((PropertyValueLongDTO)pair.Value.ValueContainer).Value);
        }

        #endregion
    }
}
